package com.xm.xmds1705083.service.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.xm.xm.dto.ResultDto;
import com.xm.xm.dto.SearchDto;
import com.xm.xm.util.DateUtils;
import com.xm.xm.util.ErrorCode;
import com.xm.xmds1705083.service.dto.DuoduoCouponRecordsDto;
import com.xm.xmds1705083.service.mapper.DuoduoCouponConfigMapper;
import com.xm.xmds1705083.service.mapper.DuoduoCouponMapper;
import com.xm.xmds1705083.service.mapper.DuoduoCouponRecordsMapper;
import com.xm.xmds1705083.service.mapper.DuoduoParkMapper;
import com.xm.xmds1705083.service.model.DuoduoCoupon;
import com.xm.xmds1705083.service.model.DuoduoCouponConfig;
import com.xm.xmds1705083.service.model.DuoduoCouponRecords;
import com.xm.xmds1705083.service.model.DuoduoPark;
import com.xm.xmds1705083.service.service.DuoduoCouponService;
import com.xm.xmds1705083.service.util.DateUtil;
import com.xm.xmds1705083.service.util.GlobalError;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.ibatis.session.RowBounds;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 杭州新苗网络科技有限公司
 * @author meihf
 * @date 2017/06/16
 * @description
*/ 
@Service("duoduoCouponService")
public class DuoduoCouponServiceImpl extends ServiceImpl<DuoduoCouponMapper,DuoduoCoupon> implements DuoduoCouponService {

    @Autowired
    DuoduoCouponMapper duoduoCouponMapper;

    @Autowired
    DuoduoCouponRecordsMapper duoduoCouponRecordsMapper;

    @Autowired
    DuoduoParkMapper duoduoParkMapper;

    @Autowired
    DuoduoCouponConfigMapper duoduoCouponConfigMapper;

    @Autowired @Qualifier("redisTemplate")
    public RedisTemplate<String,Integer> redisTemplate;

    protected Logger logger = LogManager.getLogger(getClass());

    @Override
    public ResultDto findMyCoupon(SearchDto searchDto) {
        ResultDto resultDto = new ResultDto();
        searchDto.setPageNo((searchDto.getPageNo()-1)*searchDto.getPageSize());
        try {
            //先查领取记录
            EntityWrapper entityWrapper = new EntityWrapper();
            entityWrapper.where(" userId={0} and isUsed=0 ",searchDto.getAppUserId()).orderBy("createTime",false);
            RowBounds rowBounds = new RowBounds(searchDto.getPageNo(),searchDto.getPageSize());
            List<DuoduoCouponRecords> duoduoCouponRecordsList = duoduoCouponRecordsMapper.selectPage(rowBounds,entityWrapper);
            //再看领取的优惠券是否过期如果没有过期就获取,有过期的就进行剔除
            List<DuoduoCouponRecords> duoduoCouponRecords = duoduoCouponRecordsList.stream().filter((duoduoCouponRecord ->
                duoduoCouponMapper.selectList(new EntityWrapper<DuoduoCoupon>().where(" id={0} ",duoduoCouponRecord.getCouponId())).get(0)
                        .getEndTime()>searchDto.getTime()
            )).sorted(Comparator.comparing(DuoduoCouponRecords::getCreateTime).reversed()).collect(Collectors.toList());
            if (duoduoCouponRecords.size()==0){
                resultDto.setCode(ErrorCode.C11001);
                resultDto.setMsg(ErrorCode.E11001);
                return resultDto;
            }
            JSONArray couponRecordsArr = JSONArray.fromObject(duoduoCouponRecords);
            couponRecordsArr.forEach((coupon)->{
                //先获取优惠券信息
                DuoduoCoupon duoduoCoupon = duoduoCouponMapper.selectList(new EntityWrapper<DuoduoCoupon>().
                        where(" id={0} ",((JSONObject)coupon).getInt("couponId"))).get(0);
                //塞入优惠券信息
                ((JSONObject) coupon).put("couponName",duoduoCoupon.getName());
                ((JSONObject) coupon).put("couponPic",duoduoCoupon.getPic());
                ((JSONObject) coupon).put("money",duoduoCoupon.getMoney());
                ((JSONObject) coupon).put("minMoney",duoduoCoupon.getMinMoney());
                //把有效期转成字符串
                String endTime = DateUtil.timeStamp2Date(duoduoCoupon.getEndTime(), DateUtils.PATTERN_DATE);
                ((JSONObject) coupon).put("endTime",endTime);
                //再根据parkId去查询停车场名称
                List<DuoduoPark> duoduoParkList = duoduoParkMapper.selectList(new EntityWrapper<DuoduoPark>().
                        where(" id={0} ",duoduoCoupon.getParkId()));
                if (duoduoParkList.size()==0){
                   logger.info("优惠券里面的停车场id在停车场里没有对应的值");
                }
                //塞入停车场名称
                String parkName = duoduoParkList.get(0).getParkName();
                ((JSONObject) coupon).put("parkName",parkName);
            });
            resultDto.setData(couponRecordsArr);
            resultDto.setMsg("查询成功！");
        }catch (RuntimeException e ){
            e.printStackTrace();
            resultDto.setCode(ErrorCode.C10013);
            resultDto.setMsg(ErrorCode.E10013);
        }
        return resultDto;
    }

    @Override
    public ResultDto getCoupon(SearchDto searchDto) {
        ResultDto resultDto = new ResultDto();
        searchDto.setPageNo((searchDto.getPageNo()-1)*searchDto.getPageSize());
        try {
            //先获取优惠券能够获取到的概率
            List<DuoduoCouponConfig> duoduoCouponConfigList =  duoduoCouponConfigMapper.selectList(new EntityWrapper<>());
            if (duoduoCouponConfigList.size()==0){
                resultDto.setCode(GlobalError.C11024);
                resultDto.setMsg(GlobalError.E11024);
                return resultDto;
            }
            //再看今天摇了多少次，摇的次数放到了redis里面
            DuoduoCouponConfig duoduoCouponConfig = duoduoCouponConfigList.get(0);
            String key = "xmds1705083_"+DateUtils.getNowDateTime(DateUtils.PATTERN_DATE_SIMPLE)+searchDto.getAppUserId()+"_shakeNum";
            //如果大于等于就直接返回
//            redisTemplate.boundValueOps(key).set(0);
            if (redisTemplate.hasKey(key) && redisTemplate.boundValueOps(key).get()>=duoduoCouponConfig.getShakeNum()){
                resultDto.setMsg(GlobalError.E11025);
                resultDto.setCode(GlobalError.C11025);
            }else {
                //随机一个数看在不在概率之中 看手中已经有几张优惠券，如果多余五张就不给了，小于五张给金额多些的
                List<DuoduoCouponRecords> duoduoCouponRecordsList = duoduoCouponRecordsMapper.selectList(new EntityWrapper<DuoduoCouponRecords>().
                        where(" userId={0} and isUsed=0",searchDto.getAppUserId()));
                int size = 0;
                if (duoduoCouponRecordsList.size()!=0){
                    size = duoduoCouponRecordsList.stream().filter(
                            (record)-> duoduoCouponMapper.selectById(record.getCouponId()).getEndTime()>searchDto.getTime()
                    ).collect(Collectors.toList()).size();
                }
                if (size>=5){
                    resultDto.setCode(GlobalError.C11026);
                    resultDto.setMsg(GlobalError.E11026);
                    return resultDto;
                }
                double random = Math.random();
                double probability = duoduoCouponConfigList.get(0).getProbability();
                probability = new BigDecimal(probability).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).doubleValue();
                if (random<=probability){
                    //中奖啦 先随机给一张
                    //获取可以得到的优惠券
                    List<DuoduoCoupon> duoduoCouponList = duoduoCouponMapper.selectList(new EntityWrapper<DuoduoCoupon>()
                            .where(" endTime>{0} and receiveNum<grantNum",searchDto.getTime()));
                    if (duoduoCouponList.size()==0){
                        resultDto.setCode(GlobalError.C11024);
                        resultDto.setMsg(GlobalError.E11024);
                        return resultDto;
                    }
                    Collections.shuffle(duoduoCouponList);
                    DuoduoCoupon duoduoCoupon = duoduoCouponList.get(0);
                    duoduoCoupon.setReceiveNum(duoduoCoupon.getReceiveNum()+1);
                    //先修改领取记录
                    duoduoCouponMapper.updateById(duoduoCoupon);
                    //再将记录保存到表里
                    DuoduoCouponRecords duoduoCouponRecords = new DuoduoCouponRecords();
                    duoduoCouponRecords.setCouponId(duoduoCoupon.getId());
                    duoduoCouponRecords.setUserId(searchDto.getAppUserId().intValue());
                    duoduoCouponRecords.setCreateTime(searchDto.getTime().intValue());
                    duoduoCouponRecordsMapper.insert(duoduoCouponRecords);
                    //将摇一摇次数保存到redis里面
                    if (!redisTemplate.hasKey(key)){
                        redisTemplate.boundValueOps(key).set(1);
                    }else {
                        redisTemplate.boundValueOps(key).set(redisTemplate.boundValueOps(key).get()+1);
                    }
                    //将结果返回
                    resultDto.setData(duoduoCoupon);
                }else {
                    resultDto.setCode(GlobalError.C11026);
                    resultDto.setMsg(GlobalError.E11026);
                    //将摇一摇次数保存到redis里面
                    if (!redisTemplate.hasKey(key)){
                        redisTemplate.boundValueOps(key).set(1);
                    }else {
                        redisTemplate.boundValueOps(key).set(redisTemplate.boundValueOps(key).get()+1);
                    }
                }

            }
        }catch (RuntimeException e ){
            e.printStackTrace();
            resultDto.setCode(ErrorCode.C10013);
            resultDto.setMsg(ErrorCode.E10013);
        }
        return resultDto;
    }
}

